package com.suray.wcs.web.system.controller;

import com.suray.basic.wcs.path.enums.NodeStatus;
import com.suray.basic.wcs.path.enums.NodeType;
import com.suray.basic.wcs.utils.WcsFuncUtil;
import com.suray.commin.annotation.Log;
import com.suray.commin.core.controller.BaseController;
import com.suray.commin.core.controller.ResponseData;
import com.suray.commin.core.page.TableDataInfo;
import com.suray.commin.core.utils.DateUtils;
import com.suray.commin.core.utils.SecurityUtils;
import com.suray.commin.core.utils.SpringContextHolder;
import com.suray.commin.core.utils.StringUtils;
import com.suray.commin.enmus.BusinessType;
import com.suray.system.run.license.LicenseCheckListener;
import com.suray.wcs.res.enums.RgvType;
import com.suray.wcs.service.init.SystemInit;
import com.suray.wcs.service.pojo.RgvSM;
import com.suray.wcs.service.pojo.WareHouseInfo;
import com.suray.wcs.service.resmap.WriteMap;
import com.suray.wcs.service.system.entity.RgvMapDB;
import com.suray.wcs.service.system.entity.WareHouseDB;
import com.suray.wcs.service.system.service.impl.NodeDBServiceImpl;
import com.suray.wcs.service.system.service.impl.RgvMapDBServiceImpl;
import com.suray.wcs.service.system.service.impl.WareHouseDBServiceImpl;
import com.suray.wcs.service.util.DictUtils;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.List;

/**
 * (WcsDistrict)表控制层
 *
 * @author rongbj
 * @since 2020-02-18 13:02:55
 */
@RestController
@RequestMapping("/wareHouse")
public class WareHouseDBController extends BaseController {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    private LicenseCheckListener licenseCheckListener = SpringContextHolder.getBean(LicenseCheckListener.class);
    /**
     * 服务对象
     */
    @Resource
    private WareHouseDBServiceImpl wcsDistrictService;

    @Autowired
    private NodeDBServiceImpl nodeDBService;

    @Autowired
    private RgvMapDBServiceImpl rgvMapDBService;

    /**
     * 通过条件查询数据
     *
     * @param wareHouseDB 查询条件对象
     * @return ResponseData
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list')")
    @ApiOperation("通过条件查询数据")
    @GetMapping("/list")
    public TableDataInfo getWcsDistricts(WareHouseDB wareHouseDB) {
        startPage();
        List<WareHouseDB> wareHouseDBS = wcsDistrictService.queryWareHouseList(wareHouseDB);
        return getDataTable(wareHouseDBS);
    }

    /**
     * 旋转地图
     *
     * @param distName
     * @param rotate
     * @return
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:updRotateByName')")
    @Log(title = "仓库管理", method = "旋转地图", businessType = BusinessType.UPDATE)
    @ApiOperation("旋转地图")
    @GetMapping("/updRotateByName")
    public ResponseData updRotateByName(@RequestParam(required = true) String distName,
                                        @RequestParam(required = true) Integer rotate) {
        boolean res = wcsDistrictService.updateRotateByName(distName, rotate);
        if (res)
            return ResponseData.success("旋转成功");
        else
            return ResponseData.error("请前往库区配置配置 " + distName + " 后重试");

    }

    /**
     * 新增
     *
     * @param wareHouseDB
     * @return
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:add')")
    @Log(title = "仓库管理", method = "新增", businessType = BusinessType.INSERT)
    @ApiOperation("新增")
    @PostMapping("/add")
    public ResponseData add(@Validated @RequestBody WareHouseDB wareHouseDB) {
        if (wcsDistrictService.list() != null) {
            return ResponseData.error("不允许存在多条仓库配置!");
        }
        return toAjax(wcsDistrictService.insertWcsDist(wareHouseDB));
    }

    /**
     * 根据Id获取仓库信息
     */
    @ApiOperation("根据Id获取仓库信息")
    @GetMapping(value = "/{warehouseId}")
    public ResponseData getInfo(@PathVariable Long warehouseId) {
        return ResponseData.success(wcsDistrictService.getById(warehouseId));
    }

    /**
     * 根据Id修改仓库信息
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:edit')")
    @Log(title = "仓库管理", method = "根据Id修改仓库信息", businessType = BusinessType.UPDATE)
    @ApiOperation("根据Id修改仓库信息")
    @PutMapping("/updateWareHouse")
    public ResponseData edit(@Validated @RequestBody WareHouseDB wareHouseDB) {
        try {
            if (wareHouseDB.getTaskdbCheckTime() == 0) {
                return error("任务超时阈值不可0！");
            }
            int mapVersion = wareHouseDB.getMapVersion();
            WareHouseDB curWareHouseDB = wcsDistrictService.getCurWareHouseDB();

            boolean result = wcsDistrictService.updateById(wareHouseDB);
            if (result) {
                SystemInit.RGVS.forEach(rgv -> {
                    rgv.getRgvHeart().setMapVersion(mapVersion);

                    if (rgv.checkRgvType(RgvType.RGV_SON_MOTHER)) {
                        ((RgvSM) rgv).getRgvCore().setSonRgvDirectionX(wareHouseDB.getSonRgvDirectionX());
                        ((RgvSM) rgv).getRgvCore().setSonRgvDirectionY(wareHouseDB.getSonRgvDirectionY());
                    }
                });

                if (mapVersion != curWareHouseDB.getMapVersion() ||
                        wareHouseDB.getMapDirection() != curWareHouseDB.getMapDirection()) {
                    WriteMap.write();
                }
                SystemInit.wareHouseDB = wareHouseDB;
            }
            return toAjax(result);
        } catch (IOException e) {
            return error(e.getMessage());
        }
    }


    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:edit')")
    @ApiOperation("状态修改")
    @Log(title = "仓库状态修改", method = "状态修改", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public ResponseData changeStatus(@RequestBody WareHouseDB wareHouseDB) {
        wareHouseDB.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(wcsDistrictService.updatePortStatus(wareHouseDB));
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:edit')")
    @ApiOperation("跑码修改")
    @Log(title = "仓库跑码修改", method = "跑码修改", businessType = BusinessType.UPDATE)
    @PutMapping("/changeRunFlag")
    public ResponseData changeRunFlag(@RequestBody WareHouseDB wareHouseDB) {
        wareHouseDB.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(wcsDistrictService.updatePortStatus(wareHouseDB));
    }
    /**
     * 获取库区对应层
     */
    @GetMapping(value = "/getWareHouseInfo")
    @ApiOperation(value = "获取仓库基本信息")
    public ResponseData getWareHouseInfo() {
        String wareHouseName = null;
        WareHouseDB wareHouseDB = wcsDistrictService.getOne(null);
        Integer mapRotate = null;
        if (wareHouseDB != null) {
            wareHouseName = wareHouseDB.getWarehouseName();
            mapRotate = wareHouseDB.getMapRotate();
        }
        Integer maxX = nodeDBService.getMaxX();
        Integer maxY = nodeDBService.getMaxY();
        Integer maxZ = nodeDBService.getMaxZ();
        Integer total = nodeDBService.selectCountByType(NodeType.P);
        Integer used = nodeDBService.selectCountByStatus(NodeStatus.Y);
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        String availability = numberFormat.format((float) used / (float) total * 100);
        WareHouseInfo wareHouseInfo = new WareHouseInfo(wareHouseName, maxX, maxY, maxZ, mapRotate, used, total, availability);
        wareHouseInfo.setShowFlag(nodeDBService.getCodeFlage());
        return ResponseData.success(wareHouseInfo);
    }
    /**
     * 通过条件查询数据
     *
     * @param rgvMapDB 查询条件对象
     * @return ResponseData
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:listMap')")
    @ApiOperation("通过条件查询数据")
    @GetMapping("/listMap")
    public TableDataInfo getMap(RgvMapDB rgvMapDB) {
        startPage();
        List<RgvMapDB> rgvMapDBS =rgvMapDBService.selectMapList(rgvMapDB);
        return getDataTable(rgvMapDBS);
    }
    /**
     * 新增地图
     *
     * @param rgvMapDB
     * @return
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:addMap')")
    @Log(title = "地图管理", method = "新增地图", businessType = BusinessType.INSERT)
    @ApiOperation("新增地图")
    @PostMapping("/addMap")
    public ResponseData addMap(@Validated @RequestBody RgvMapDB rgvMapDB) {
        try {
            if (rgvMapDB.getLayer() == null) {
                return ResponseData.error("请输入层数");
            }

            if (rgvMapDB.getMap() == null) {
                return ResponseData.error("请输入地图名称");
            }

            List<RgvMapDB> rgvMapDBS = rgvMapDBService.list();
            for (RgvMapDB mapDB : rgvMapDBS) {
                if (mapDB.getLayer().equals(rgvMapDB.getLayer())) {
                    return ResponseData.error("已存在" + rgvMapDB.getLayer() + "层的地图，请修改为其它层");
                }

                if (mapDB.getMap().equals(rgvMapDB.getMap())) {
                    return ResponseData.error("已存在名称为 " + rgvMapDB.getMap() + " 的地图，请修改为其它名称");
                }
            }

            return toAjax(SystemInit.rgvMapManage.addRgvMap(rgvMapDB));
        } catch (Exception e) {
            WcsFuncUtil.exceptionLog(e, this.getClass());
            return ResponseData.error("新增地图 失败:" + e.getMessage());
        }
    }

    /**
     * 根据Id获取地图信息
     */
    @ApiOperation("根据Id获取地图信息")
    @GetMapping(value = "getMap/{id}")
    public ResponseData getMap(@PathVariable Long id) {
        return ResponseData.success(rgvMapDBService.getById(id));
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:edit')")
    @ApiOperation("地图修改")
    @Log(title = "地图管理", method = "地图修改", businessType = BusinessType.UPDATE)
    @PutMapping("/updateMap")
    public ResponseData updateMap(@RequestBody RgvMapDB rgvMapDB) {
        try {
            if (rgvMapDB.getLayer() == null) {
                return ResponseData.error("请输入层数");
            }

            if (rgvMapDB.getMap() == null) {
                return ResponseData.error("请输入地图名称");
            }

            List<RgvMapDB> rgvMapDBS = rgvMapDBService.list();
            RgvMapDB oldRgvMapDB = null;
            for (RgvMapDB mapDB : rgvMapDBS) {
                if (mapDB.getId().equals(rgvMapDB.getId())) {
                    oldRgvMapDB = mapDB;
                    continue;
                }

                if (mapDB.getLayer().equals(rgvMapDB.getLayer())) {
                    return ResponseData.error("已存在" + rgvMapDB.getLayer() + "层的地图，请修改为其它层");
                }

                if (mapDB.getMap().equals(rgvMapDB.getMap())) {
                    return ResponseData.error("已存在名称为 " + rgvMapDB.getMap() + " 的地图，请修改为其它名称");
                }
            }

            return toAjax(SystemInit.rgvMapManage.changeRgvMap(oldRgvMapDB, rgvMapDB));
        } catch (Exception e) {
            WcsFuncUtil.exceptionLog(e, this.getClass());
            return ResponseData.error("修改地图 失败:" + e.getMessage());
        }
    }

    /**
     * 删除地图
     *
     * @param id
     * @return
     */
    @Log(title = "地图管理", method = "删除地图", businessType = BusinessType.DELETE)
    @DeleteMapping(value = "/delete/{id}")
    @ApiOperation(value = "删除地图")
    @PreAuthorize("@ss.hasPermi('map:remove')")
    public ResponseData delMap(@PathVariable Long id) {
        try {
            return toAjax(SystemInit.rgvMapManage.deleteRgvMap(id));
        } catch (Exception e) {
            WcsFuncUtil.exceptionLog(e, this.getClass());
            return ResponseData.error("删除地图 失败:" + e.getMessage());
        }
    }

    /**
     *
     * @param file 文件
     * @return code:0(成功),-1(失败,出现错误),-2(未登录状态) data:数据 message:传递到页面的数据
     */
    @Log(title = "上传证书文件", method = "上传证书文件", businessType = BusinessType.UPDATE)
    @ApiOperation("上传证书文件")
    @PostMapping("/importFile")
    @ResponseBody
    public ResponseData importData(MultipartFile file) {
        log.info("更新证书文件");
        try {
            byte[] bytes = file.getBytes();
            String filename = file.getOriginalFilename();
            if ("license.lic".equals(filename)) {
                licenseCheckListener.updateLicense(bytes, true);
            } else {
                licenseCheckListener.updateLicense(bytes, false);
            }
            licenseCheckListener.refreshLicense();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseData.success();
    }

    /**
     *
     */
    @Log(title = "获取证书过期时间", method = "获取证书过期时间", businessType = BusinessType.UPDATE)
    @ApiOperation("获取证书过期时间")
    @GetMapping("/getExpirationTime")
    @ResponseBody
    public ResponseData getExpirationTime() {
        long days = DateUtils.getDatePoorDays(SystemInit.expirationDate, DateUtils.getNowDate());
        if (days == 0) {
            if (StringUtils.isNotEmpty(SystemInit.expirationMsg)) {
                return ResponseData.error(SystemInit.expirationMsg, days);
            } else {
                return ResponseData.error("证书已过期", days);
            }
        }
        return ResponseData.success(days);
    }

}
